package com.yanqu.road.server.manager.beautyescort;

import com.yanqu.road.entity.beautyescort.*;
import com.yanqu.road.entity.beautyescort.enums.eEscortCartState;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.logic.bussiness.beautyescort.BeautyEscortBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.server.manger.BeautyEscortConfigMgr;
import com.yanqu.road.server.manger.ConfigMgr;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.pb.beautyescort.BeautyEscortProto;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 单个玩家包装
 */
public class CrossEscortPlayerWrap {

    /**
     * 玩家数据
     */
    private EscortUserData userData;

    /**
     * 玩家基础数据
     */
    private UserBaseInfo userBaseInfo;

    /**
     * 镖车数据
     */
    private Map<Integer, EscortCartData> cartDataMap = new ConcurrentHashMap<>();

    /**
     * 走镖战报
     */
    private Map<Long, EscortReport> escortReportMap = new ConcurrentHashMap<>();

    /**
     * 路线图玩家缓存
     */
    Map<Integer, CrossEscortPlayerWrap> roadMapPlayer = new ConcurrentHashMap<>();

    /**
     * 记录上次强制刷新后，劫持的玩家和镖车，每次强制刷新时重置   缓存
     */
    Map<Long, Long> robbedDartMap = new ConcurrentHashMap<>();

    public CrossEscortPlayerWrap() {
    }

    public CrossEscortPlayerWrap(EscortUserData userData, UserBaseInfo userBaseInfo) {
        this.userData = userData;
        this.userBaseInfo = userBaseInfo;
    }

    public boolean save() {

        for (Map.Entry<Integer, EscortCartData> cartDataEntry : cartDataMap.entrySet()) {
            if(cartDataEntry.getValue().isInsertOption()){
                BeautyEscortBussiness.addEscortCartData(cartDataEntry.getValue());
            }else if(cartDataEntry.getValue().isUpdateOption()){
                BeautyEscortBussiness.updateEscortCartData(cartDataEntry.getValue());
            }
        }

        if(userData.isInsertOption()){
            BeautyEscortBussiness.addEscortUserData(userData);
        }else if(userData.isUpdateOption()){
            BeautyEscortBussiness.updateEscortUserData(userData);
        }

        for (Map.Entry<Long, EscortReport> reportEntry : escortReportMap.entrySet()) {
            if(reportEntry.getValue().isInsertOption()){
                BeautyEscortBussiness.addEscortReport(reportEntry.getValue());
            }else if(reportEntry.getValue().isUpdateOption()){
                BeautyEscortBussiness.updateEscortReport(reportEntry.getValue());
            }
        }

        moveReportData();

        return true;
    }

    /**
     * 移除过期战报(保留两周)
     */
    private void moveReportData() {
        int preWeekId = CrossBeautyEscortRankMgr.getPreWeekId();
        try {
            Iterator<Long> iterator = escortReportMap.keySet().iterator();
            while(iterator.hasNext()){
                long reportKey = iterator.next();
                EscortReport report = escortReportMap.get(reportKey);
                if(report != null){
                    //移除上上周
                    if(preWeekId > report.getWeekId() && !report.isDirty()){
                        iterator.remove();
                        continue;
                    }
                    //移除已删除
                  /*  if(report.isDel() && !report.isDirty()){
                        iterator.remove();
                        continue;
                    }*/
                }
            }
        }catch (Exception e){
            CrossBeautyEscortMgr.getLogger().error("remove user {} report error", userData.getUserId(), e);
        }
    }

    /**
     * 生成押镖车信息
     *
     * @param clientId
     * @param type
     * @param dispatchList
     * @return
     */
    public EscortCartDataHelper genEscortCartData(int clientId, int type, List<EscortBeautyDispatch> dispatchList,
            boolean autoAccelerate, int accelerateTime) {
        EscortCartDataHelper helper = new EscortCartDataHelper();
        EscortCartData idleCart;
        synchronized (userData) {
            //检查美女是否在走镖中
            List<Integer> beautyIdList = getEscortingBeautyIdList();
            for (EscortBeautyDispatch dispatch : dispatchList) {
                if (beautyIdList.contains(dispatch.getBeautyId())) {
                    helper.setRet(GameErrorCode.E_BEAUTY_ESCORT_HAD_IN_ESCORT);
                    return helper;
                }
            }
            idleCart = getIdleEscortCartData();
            if (idleCart == null) {
                helper.setRet(GameErrorCode.E_BEAUTY_ESCORT_NO_IDLE_CART);
                return helper;
            }
            if (!isIdle(idleCart)) {
                helper.setRet(GameErrorCode.E_BEAUTY_ESCORT_NO_IDLE_CART);
                return helper;
            }
            userData.getClientList().remove(0);
            EscortDartTypeInfo typeInfo = ConfigMgr.getDartTypeInfoMap().get(type);
            resetCart(idleCart);
            idleCart.setState(eEscortCartState.Escorting.getIntValue());
            idleCart.setClientId(clientId);
            idleCart.setDartId(getNextDartId());
            idleCart.setDartTypeId(typeInfo.getId());
            idleCart.setStartTime(DateHelper.getCurrentSecond());
            idleCart.setBeautyDispatchList(dispatchList);
            idleCart.setTakeTime(typeInfo.getTakeTime());
            if(autoAccelerate){//自动加速
                idleCart.setAutoHandleEvent(true);
                if(accelerateTime >= idleCart.getTakeTime()) {
                    idleCart.setReduceTime(idleCart.getTakeTime());
                }else {
                    idleCart.setReduceTime(accelerateTime);
                }
                calCartStateWithEvent(idleCart);
            }
        }
        helper.setRet(0);
        helper.setIdleCart(idleCart);
        return helper;
    }

    /**
     * 接镖+美女派遣(十连)
     */
    public int acceptAndDispatchDartTenTimes(int clientId, int type, List<EscortBeautyDispatch> dispatchList, String allConsume) {

        BeautyEscortProto.CrossBeautyEscortAcceptDispatchTenRespMsg.Builder respMsg = BeautyEscortProto.CrossBeautyEscortAcceptDispatchTenRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setAllConsume(allConsume);
        respMsg.setUnionLv(userData.getUnionLv());
        respMsg.setUnionUid(userBaseInfo.getUnionUid());
        //走镖奖励
        EscortDartTypeInfo typeInfo = ConfigMgr.getDartTypeInfoMap().get(type);
        Property dartReward = PropertyHelper.parseStringToProperty(typeInfo.getRewards());
        dartReward.rideProperty(10);
        respMsg.setReward(PropertyHelper.parsePropertyToString(dartReward));

        Random random = new Random();
        //全部使用镖车0
        //随机十个委托人？
        //事件奖励
        Property eventReward = new Property();
        for (int i = 0; i < 10; i++) {
            if(userData.getDayEventNum() < GameConfig.ESCORT_EVENT_TIMES_PER_DAY) {
                //计算当前概率加成千分比
                int passSecond = random.nextInt(typeInfo.getTakeTime() * 60);
                int addition = getEventTriggerAddition(passSecond, 0, typeInfo.getTakeTime());
                int point = addition / ConfigMgr.getEscortEventProbability().get(2);
                if (point == 0) {
                    continue;
                }
                EscortBeautyEventBossInfo event = null;
                for(int p = 0; p < point; p++){
                    if(triggerEvent(p * ConfigMgr.getEscortEventProbability().get(2))){
                        //随机一个事件
                        EscortBeautyEventBossInfo eventBossInfo = BeautyEscortConfigMgr.getRandomEventInfo(userData.getUnionLv());
                        if(eventBossInfo != null) {
                            event = eventBossInfo;
                            break;
                        }
                    }
                }
                if(event != null){
                    BeautyEscortProto.BeautyEscortEventHandleMsg.Builder builder = BeautyEscortProto.BeautyEscortEventHandleMsg.newBuilder();
                    builder.setRound(i + 1);
                    builder.setEventId(event.getId());
                    builder.setDamage(event.getHp());
                    builder.setReward("");
                    EscortBeautyEventBossInfo bossInfo = BeautyEscortConfigMgr.getEventBossInfoMap().get(event.getId());
                    if(bossInfo != null){
                        Property baseRewards = new Property();
                        if(!StringUtils.isNullOrEmpty(bossInfo.getBaseRewards())){
                            baseRewards = PropertyHelper.parseStringToProperty(bossInfo.getBaseRewards());
                        }
                        String reward = getEventReward(true, event.getHp(), bossInfo);
                        baseRewards.addProperty(PropertyHelper.parseStringToProperty(reward));
                        builder.setReward(PropertyHelper.parsePropertyToString(baseRewards));

                        eventReward.addProperty(baseRewards);
                    }
                    respMsg.addEvent(builder);
                }
            }
        }

        respMsg.setEventReward(PropertyHelper.parsePropertyToString(eventReward));

        for (EscortBeautyDispatch dispatch : dispatchList) {
            respMsg.addBeautyId(dispatch.getBeautyId());
        }

        MessageHelper.sendPacket(userData.getServerId(), userData.getUserId(), YanQuMessageUtils.buildMessage(Protocol.S_BEAUTY_ESCORT_ACCEPT_DISPATCH_BEAUTY_TEN_TIMES_FROM_CROSS, respMsg));
        return 0;
    }

    /**
     * 接镖+美女派遣
     */
    public int acceptAndDispatchDart(int clientId, int type, List<EscortBeautyDispatch> dispatchList, List<Integer> buyList,
             String buyBeautyConsume, boolean autoAccelerate, int needAccelerateCount, int accelerateTime) {
        if(clientId != userData.getClientList().get(0)){
            return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
        }
        EscortCartDataHelper helper = genEscortCartData(clientId, type, dispatchList, autoAccelerate, accelerateTime);
        if (helper.getRet() != 0) {
            return helper.getRet();
        }
        BeautyEscortProto.CrossBeautyEscortAcceptDispatchRespMsg.Builder respMsg = BeautyEscortProto.CrossBeautyEscortAcceptDispatchRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setClient(clientId);
        respMsg.setCartId(helper.getIdleCart().getCartId());
        respMsg.setTypeId(type);
        respMsg.setDartId(helper.getIdleCart().getDartId());
        respMsg.addAllBeauty(CrossBeautyEscortMgr.parseBeautyDispatchBuilderList(dispatchList));
        respMsg.addAllBuyBeauty(buyList);
        respMsg.setBuyBeautyConsume(buyBeautyConsume);
        respMsg.setAutoAccelerate(autoAccelerate);
        respMsg.setNeedAccelerateCount(needAccelerateCount);
        MessageHelper.sendPacket(userData.getServerId(), userData.getUserId(), YanQuMessageUtils.buildMessage(Protocol.S_BEAUTY_ESCORT_ACCEPT_DISPATCH_BEAUTY_FROM_CROSS, respMsg));
        return 0;
    }

    /**
     * 路线-地图玩家（获取+刷新）
     */
    public int roadMap(int type, String unionUid) {
        resetUserData();
        //CrossBeautyEscortMgr.getLogger().info("ESCORT_ROAD_MAP_PLAYER_NUM: {}", GameConfig.ESCORT_ROAD_MAP_PLAYER_NUM);
        //强制刷新
        if(type == 1){
            refreshRoadMap(unionUid);
            //强制刷新需要同步区服，扣除消耗
            BeautyEscortProto.CrossBeautyEscortRoadMapRespMsg.Builder respMsg = BeautyEscortProto.CrossBeautyEscortRoadMapRespMsg.newBuilder();
            respMsg.setRet(0);
            respMsg.setType(type);
            MessageHelper.sendPacket(userData.getServerId(), userData.getUserId(), YanQuMessageUtils.buildMessage(Protocol.S_BEAUTY_ESCORT_ROAD_MAP_REFRESH_FROM_CROSS, respMsg));
        }else {
            //判定是否需要强制刷新
            if(isForceRefresh()){
                refreshRoadMap(unionUid);
            }else {
                //开放时间内，正常刷新
                if(ConfigMgr.isEscortTimeInDay()){
                    boolean normalChange = normalRefreshRoadMap(unionUid);
                    boolean npcChange = clearFinishNpc();
                    if (normalChange || npcChange) {
                        addRoadMapCartFromNPC();
                    }else if(userData.getRoadMapNPCUser().size() == 0){
                        refreshRoadMapCartFromNPC();
                    }
                }else {
                    //非开放时间内，需清空NPC
                    normalRefreshRoadMap(unionUid);
                    if(userData.getRoadMapNPCUser().size() != 0) {
                        userData.setRoadMapNPCUser(new HashMap<>());
                    }
                }
            }
        }
        BeautyEscortProto.BeautyEscortRoadMapRespMsg.Builder respMsg = BeautyEscortProto.BeautyEscortRoadMapRespMsg.newBuilder();
        respMsg.setRet(0);
        BeautyEscortProto.BeautyEscortRoadMapPlayerTemp.Builder playerBuilder = getRoadMapPlayerBuilder(0, userData.getUserId(), userData.getEnemyList(), 0);
        playerBuilder.setEnemy(false);
        respMsg.setMe(playerBuilder);
        for (Map.Entry<Integer, CrossEscortPlayerWrap> playerWrapEntry : roadMapPlayer.entrySet()) {
            //劫过的走镖id
            long dartId = 0;
            long mapUserId = playerWrapEntry.getValue().getUserData().getUserId();
            if(robbedDartMap.containsKey(mapUserId)){
                dartId = robbedDartMap.get(mapUserId);
            }
            respMsg.addRoadMapPlayer(playerWrapEntry.getValue().getRoadMapPlayerBuilder(playerWrapEntry.getKey(), userData.getUserId(),  userData.getEnemyList(), dartId));
        }
        //NPC
        respMsg.addAllRoadMapPlayer(getAllRoadMapNPCPlayer());
        MessageHelper.sendPacket(userData.getServerId(), userData.getUserId(), YanQuMessageUtils.buildMessage(Protocol.U_BEAUTY_ESCORT_ROAD_MAP, respMsg));
        return 0;
    }

    /**
     * 是否全部刷新
     * 条件：所有镖车都被自己劫持过
     */
    private boolean isForceRefresh() {
        //所有NPC都被劫过
        int npcSize = userData.getRoadMapNPCUser().size();
        if(npcSize != 0) {
            for (Map.Entry<Integer, EscortBeautyMapNpc> mapNpcEntry : userData.getRoadMapNPCUser().entrySet()) {
                if (mapNpcEntry.getValue().isRobbed()) {
                    npcSize--;
                }
            }
        }
        //未全部劫持过
        if(roadMapPlayer.size() != robbedDartMap.size() || npcSize != 0){
            return false;
        }
        return true;
    }

    /**
     * 重置仇人
     */
    private void resetUserData() {
        Date monday = DateHelper.getThisWeekMonday(new Date());
        long time = monday.getTime();
        if(time > userData.getResetTime()){
            synchronized (userData){
                userData.setEnemyList(new ArrayList<>());
                userData.setResetTime(time);
            }
        }
    }

    /**
     * 常规刷新地图玩家
     */
    private boolean normalRefreshRoadMap(String unionUid) {
        if(unionUid == null){
            unionUid = userBaseInfo.getUnionUid();
        }
        //尝试先从db初始化
        boolean update = initTempRoadMapPlayer();
        update = update || checkAndRemoveRoadMapCart();
        //补充随机玩家
        //待填充位置
        List<Integer> positionList = new ArrayList<>();
        for(int i = 1; i <= CrossBeautyEscortMgr.ROAD_MAP_POSITION_NUM; i++){
            if(!roadMapPlayer.containsKey(i)){
                positionList.add(i);
            }
        }
        if(roadMapPlayer.size() < GameConfig.ESCORT_ROAD_MAP_PLAYER_NUM){
            Random random = new Random();
            List<Long> hasUserId = new ArrayList<>();
            for (Map.Entry<Integer, CrossEscortPlayerWrap> playerWrapEntry : roadMapPlayer.entrySet()) {
                hasUserId.add(playerWrapEntry.getValue().getUserData().getUserId());
            }
            List<CrossEscortPlayerWrap> randomList = CrossBeautyEscortMgr.randomRoadMapPlayerInGroup(userData.getServerId(), userData.getUserId(), unionUid, hasUserId);

            synchronized (roadMapPlayer) {
                //随机位置填充玩家
                while (positionList.size() > 0 && randomList.size() > 0 && roadMapPlayer.size() < GameConfig.ESCORT_ROAD_MAP_PLAYER_NUM) {
                    int idx = random.nextInt(positionList.size());
                    int position = positionList.remove(idx);
                    //随机选玩家
                    int idxUser = random.nextInt(randomList.size());
                    CrossEscortPlayerWrap playerWrap = randomList.remove(idxUser);
                    roadMapPlayer.put(position, playerWrap);

                    CrossBeautyEscortMgr.getLogger().debug("{} add position {} user {}", userData.getUserId(), position, playerWrap.getUserData().getUserId());
                    update = true;
                }
            }
        }
        if(update){
            updateRoadMapUserForUser();
        }
        return update;
    }

    /**
     * 地图NPC刷新（全替换）
     */
    private void refreshRoadMapCartFromNPC() {
        if(roadMapPlayer.size() < GameConfig.ESCORT_ROAD_MAP_PLAYER_NUM){
            Random random = new Random();
            List<Integer> npcList = new ArrayList<>();
            for (Map.Entry<Integer, EscortBeautyMapNpc> entry : userData.getRoadMapNPCUser().entrySet()) {
                if(!npcList.contains(entry.getValue().getId())) {
                    npcList.add(entry.getValue().getId());
                }
            }
            //出现的NPC个数限制
            int num = GameConfig.ESCORT_ROAD_MAP_PLAYER_NUM - roadMapPlayer.size();
            if(num > GameConfig.ESCORT_NPC_DISPLAY_NUM){
                num = GameConfig.ESCORT_NPC_DISPLAY_NUM;
            }
            List<EscortBeautyCartNPCInfo> npcInfos = ConfigMgr.randomCartNPC(num, npcList);
            Map<Integer, EscortBeautyMapNpc> tempRoadMapNPCMap = new HashMap<>();
            //待填充位置
            List<Integer> positionList = new ArrayList<>();
            for(int i = 1; i <= CrossBeautyEscortMgr.ROAD_MAP_POSITION_NUM; i++){
                //未填充玩家的位置
                if(!roadMapPlayer.containsKey(i)){
                    positionList.add(i);
                }
            }

            //随机填充NPC
            int currentSecond = DateHelper.getCurrentSecond();
            while(positionList.size() > 0 && npcInfos.size() > 0){
                int idx = random.nextInt(positionList.size());
                int idxUser = random.nextInt(npcInfos.size());
                EscortBeautyCartNPCInfo npcInfo = npcInfos.remove(idxUser);
                EscortBeautyMapNpc npc = new EscortBeautyMapNpc(npcInfo.getId(), currentSecond);
                tempRoadMapNPCMap.put(positionList.remove(idx), npc);
            }
            userData.setRoadMapNPCUser(tempRoadMapNPCMap);
        }else {
            if(userData.getRoadMapNPCUser().size() != 0) {
                userData.setRoadMapNPCUser(new HashMap<>());
            }
        }
    }

    /**
     * 地图NPC补充(按点位)
     */
    private void addRoadMapCartFromNPC() {
        if(roadMapPlayer.size() < GameConfig.ESCORT_ROAD_MAP_PLAYER_NUM){
            //是否踢除NPC
            if(roadMapPlayer.size() + userData.getRoadMapNPCUser().size() > GameConfig.ESCORT_ROAD_MAP_PLAYER_NUM){
                int moveCount = GameConfig.ESCORT_ROAD_MAP_PLAYER_NUM - roadMapPlayer.size() - userData.getRoadMapNPCUser().size();
                Iterator<Integer> iterator = userData.getRoadMapNPCUser().keySet().iterator();
                while (iterator.hasNext()){
                    int position = iterator.next();
                    if(roadMapPlayer.containsKey(position)){
                        iterator.remove();
                        moveCount--;
                    }
                }
                if(moveCount > 0){
                    iterator = userData.getRoadMapNPCUser().keySet().iterator();
                    while (iterator.hasNext()){
                        iterator.remove();
                        moveCount--;
                        if(moveCount == 0){
                            break;
                        }
                    }
                }
                userData.setUpdateOption();
                return;
            }
            //可填充NPC位置
            List<Integer> positionList = new ArrayList<>();
            for(int i = 1; i <= CrossBeautyEscortMgr.ROAD_MAP_POSITION_NUM; i++) {
                if (!roadMapPlayer.containsKey(i)) {
                    positionList.add(i);
                }
            }
            Random random = new Random();
            //已有NPC位置
            List<Integer> npcPosition = new ArrayList<>();
            for (int position : userData.getRoadMapNPCUser().keySet()) {
                npcPosition.add(position);
            }
            for (int position : npcPosition) {
                if(positionList.size() == 0){
                    break;
                }
                //给玩家腾位置
                if(roadMapPlayer.containsKey(position)){
                    int idx = random.nextInt(positionList.size());
                    int newPosition = positionList.remove(idx);
                    EscortBeautyMapNpc npc = userData.getRoadMapNPCUser().remove(position);
                    if(npc != null) {
                        userData.getRoadMapNPCUser().put(newPosition, npc);
                    }
                }
            }
            //NPC已达上限
            if(userData.getRoadMapNPCUser().size() == GameConfig.ESCORT_NPC_DISPLAY_NUM){
                return;
            }
            //NPC未达上限、补充
            List<Integer> npcList = new ArrayList<>();
            for (Map.Entry<Integer, EscortBeautyMapNpc> entry : userData.getRoadMapNPCUser().entrySet()) {
                if(!npcList.contains(entry.getValue().getId())) {
                    npcList.add(entry.getValue().getId());
                }
            }
            //出现的NPC个数限制
            int num = GameConfig.ESCORT_ROAD_MAP_PLAYER_NUM - userData.getRoadMapNPCUser().size() - roadMapPlayer.size();
            if(num > GameConfig.ESCORT_NPC_DISPLAY_NUM){
                num = GameConfig.ESCORT_NPC_DISPLAY_NUM;
            }
            int currentSecond = DateHelper.getCurrentSecond();
            if(num > 0 && positionList.size() > 0){
                List<EscortBeautyCartNPCInfo> npcInfos = ConfigMgr.randomCartNPC(num, npcList);
                int addNum = 0;
                while(positionList.size() > 0 && addNum < npcInfos.size()){
                    int idx = random.nextInt(positionList.size());
                    EscortBeautyCartNPCInfo npcInfo = npcInfos.get(addNum);
                    EscortBeautyMapNpc npc = new EscortBeautyMapNpc(npcInfo.getId(), currentSecond);
                    userData.getRoadMapNPCUser().put(positionList.remove(idx), npc);
                    addNum++;
                }
            }
            userData.setUpdateOption();
        }else {
            if(userData.getRoadMapNPCUser().size() != 0) {
                userData.setRoadMapNPCUser(new HashMap<>());
                userData.setUpdateOption();
            }
        }
    }

    /**
     * 清除NPC
     */
    private boolean clearFinishNpc() {
        //清除NPC
        boolean change = false;
        int takeTime = 60 * ConfigMgr.getRobotDartCartType().getTakeTime();
        int currentSecond = DateHelper.getCurrentSecond();
        Iterator<Integer> iterator = userData.getRoadMapNPCUser().keySet().iterator();
        while (iterator.hasNext()){
            int position = iterator.next();
            EscortBeautyMapNpc npc = userData.getRoadMapNPCUser().get(position);
            if(npc == null){
                iterator.remove();
                change = true;
                continue;
            }
            if(currentSecond - npc.getStart() >= takeTime){
                iterator.remove();
                change = true;
                continue;
            }
        }
        return change;
    }

    /**
     * 强制刷新地图
     */
    private void refreshRoadMap(String unionUid) {
        if(unionUid == null){
            unionUid = userBaseInfo.getUnionUid();
        }
        Map<Integer, CrossEscortPlayerWrap> tempRoadMapPlayer = new HashMap<>();
        //清除上次劫持缓存
        preRefreshMap();
        //随机玩家
        List<CrossEscortPlayerWrap> randomList = CrossBeautyEscortMgr.randomRoadMapPlayerInGroup(userData.getServerId(), userData.getUserId(), unionUid, new ArrayList<>());

        //所有位置
        List<Integer> positionList = new ArrayList<>();
        for(int i = 1; i <= CrossBeautyEscortMgr.ROAD_MAP_POSITION_NUM; i++){
            positionList.add(i);
        }
        Random random = new Random();
        while (randomList.size() > 0 && positionList.size() > 0 && tempRoadMapPlayer.size() < GameConfig.ESCORT_ROAD_MAP_PLAYER_NUM){
            //随机位置
            int idx = random.nextInt(positionList.size());
            int position = positionList.remove(idx);
            //随机选玩家
            int idxUser = random.nextInt(randomList.size());
            CrossEscortPlayerWrap playerWrap = randomList.remove(idxUser);
            tempRoadMapPlayer.put(position, playerWrap);
        }
        //替换玩家
        roadMapPlayer = tempRoadMapPlayer;
        updateRoadMapUserForUser();

        //NPC,正常时间才能出现NPC
        if(ConfigMgr.isEscortTimeInDay()){
            refreshRoadMapCartFromNPC();
        }else {
            if(userData.getRoadMapNPCUser().size() != 0) {
                userData.setRoadMapNPCUser(new HashMap<>());
            }
        }
    }

    /**
     * 存储地图玩家
     */
    private void updateRoadMapUserForUser() {
        Map<Integer, Long> serverUserMap = new HashMap<>();
        for (Map.Entry<Integer, CrossEscortPlayerWrap> playerWrapEntry : roadMapPlayer.entrySet()) {
            EscortUserData escortUserData = playerWrapEntry.getValue().getUserData();
            serverUserMap.put(playerWrapEntry.getKey(), escortUserData.getUserId());
        }
        userData.setRoadMapUser(serverUserMap);
    }

    /**
     * 检查及移除地图玩家(单点移除)
     * 条件：玩家沒有走镖；劫持过的镖车玩家走镖（不在给玩家的其他走镖镖车）；玩家不在区服分组范围内；同一个商会
     */
    private boolean checkAndRemoveRoadMapCart() {
        boolean change = false;
        int groupId = CrossBeautyEscortRankMgr.getGroupId(userData.getServerId());
        Set<Long> serverIdSet = CrossBeautyEscortRankMgr.getGroupServer(groupId);
        synchronized (roadMapPlayer) {
            Iterator<Integer> iterator = roadMapPlayer.keySet().iterator();
            while (iterator.hasNext()) {
                int position = iterator.next();
                CrossEscortPlayerWrap escortPlayer = roadMapPlayer.get(position);
                //脏数据
                if (escortPlayer == null) {
                    iterator.remove();
                    continue;
                }
                //沒有走镖中的镖车
                if (escortPlayer.getFirstEscortingCart() == null) {
                    iterator.remove();
                    robbedDartMap.remove(escortPlayer.getUserData().getUserId());
                    change = true;
                    continue;
                }
                //劫过的镖车已完成，也要移除
                if (robbedDartMap.containsKey(escortPlayer.getUserData().getUserId())) {
                    long dartId = robbedDartMap.get(escortPlayer.getUserData().getUserId());
                    EscortCartData cartData = getCartDataByDartId(dartId);
                    if (cartData != null) {
                        int state = getCartState(cartData);
                        if (state == eEscortCartState.Finish.getIntValue()) {
                            iterator.remove();
                            robbedDartMap.remove(escortPlayer.getUserData().getUserId());
                            change = true;
                            continue;
                        }
                    }
                }
                //同一个商会
                if (Objects.equals(escortPlayer.getUserBaseInfo().getUnionUid(), userBaseInfo.getUnionUid())) {
                    iterator.remove();
                    robbedDartMap.remove(escortPlayer.getUserData().getUserId());
                    change = true;
                    continue;
                }
                //不在区服
                if (!serverIdSet.contains(escortPlayer.getUserData().getServerId())) {
                    iterator.remove();
                    robbedDartMap.remove(escortPlayer.getUserData().getUserId());
                    change = true;
                }
            }
        }
        return change;
    }

    /**
     * 初始地图玩家
     */
    private boolean initTempRoadMapPlayer() {
        boolean change = false;
        if(roadMapPlayer.size() == 0 && userData.getRoadMapUser().size() != 0) {
            List<Long> serverIdList = CrossBeautyEscortRankMgr.getGroupServer(userData.getServerId());
            Map<Long, CrossEscortPlayerWrap> playerWrapMap = new HashMap<>();
            Iterator<Long> iterator = userData.getRoadMapUser().values().iterator();
            while (iterator.hasNext()) {
                long userId = iterator.next();
                long serverId = CrossBeautyEscortMgr.getUserServerId(userId);
                if(serverId == 0 || !serverIdList.contains(serverId)){
                    iterator.remove();
                    change = true;
                    continue;
                }
                CrossEscortPlayerWrap escortPlayer = CrossBeautyEscortMgr.getEscortPlayer(serverId, userId);
                if (escortPlayer == null) {
                    iterator.remove();
                    change = true;
                    continue;
                }
                if(escortPlayer.getFirstEscortingCart() == null){
                    iterator.remove();
                    change = true;
                    continue;
                }
                playerWrapMap.put(userId, escortPlayer);
            }
            for (Map.Entry<Integer, Long> serverUserEntry : userData.getRoadMapUser().entrySet()) {
                roadMapPlayer.put(serverUserEntry.getKey(), playerWrapMap.get(serverUserEntry.getValue()));
            }
        }
        return change;
    }

    /**
     * 劫镖
     */
    public int robCart(CrossEscortPlayerWrap targetPlayer, long enemyDartId, List<Integer> buyBeautyList, List<EscortBeautyDispatch> dispatchList, int position, String buyConsume) {
        EscortCartData cartData = targetPlayer.getCartDataByDartId(enemyDartId);
        if(cartData == null){
            return GameErrorCode.E_BEAUTY_ESCORT_CART_NO_EXIST;
        }
        if(cartData.getState() != eEscortCartState.Escorting.getIntValue()){
            return GameErrorCode.E_BEAUTY_ESCORT_IS_FINISH;
        }
        int startTime;
        boolean win;
        int robbedTime;
        int type;
        BeautyEscortProto.BeautyEscortCartTemp.Builder enemyCartBuilder;
        //判定劫镖次数
        synchronized (cartData) {//锁对手的镖车
            int state = targetPlayer.getCartState(cartData);
            if (state != eEscortCartState.Escorting.getIntValue()) {
                return GameErrorCode.E_BEAUTY_ESCORT_IS_FINISH;
            }
            if(cartData.getEnemy().contains(userData.getUserId())){
                return GameErrorCode.E_BEAUTY_ESCORT_CAN_NOT_ROB_SAME_DART;
            }
            if(cartData.getRobbedTimes() >= ConfigMgr.getMaxRobTimesInLoss()){
                return GameErrorCode.E_BEAUTY_ESCORT_CART_HAD_ROBBED_MANY;
            }
            //temp
            List<EscortBeautyDispatch> enemyCopy = new ArrayList<>(cartData.getBeautyDispatchList());
            win = fight(dispatchList, enemyCopy);
            robbedTime = cartData.getRobbedTimes();

            if(win) {
                //添加劫镖标识与次数
                if(cartData.getRobbedTimes() < ConfigMgr.getMaxRobTimesInLoss()) {
                    cartData.setRobbedTimes(cartData.getRobbedTimes() + 1);
                }
                //继续记录，但显示只取前几
                cartData.addEnemy(userData.getUserId());
            }
            startTime = cartData.getStartTime();
            type = cartData.getDartTypeId();
            enemyCartBuilder = BeautyEscortProto.BeautyEscortCartTemp.newBuilder();
            enemyCartBuilder.setCartId(cartData.getCartId());
            enemyCartBuilder.setDartId(enemyDartId);
            enemyCartBuilder.setCartType(cartData.getDartTypeId());
            enemyCartBuilder.setState(cartData.getState());
            enemyCartBuilder.setEventHandle(cartData.getEvent().isEnd());
            enemyCartBuilder.setStartTime(cartData.getStartTime());
            enemyCartBuilder.addAllBeauty(CrossBeautyEscortMgr.parseBeautyDispatchBuilderList(enemyCopy));
        }

        BeautyEscortProto.CrossBeautyEscortRobCartRespMsg.Builder respMsg = BeautyEscortProto.CrossBeautyEscortRobCartRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.addAllBeauty(CrossBeautyEscortMgr.parseBeautyDispatchBuilderList(dispatchList));
        EscortReport report;
        BeautyEscortProto.BeautyEscortRobbedNotifyMsg.Builder notifyMsg = null;
        if (win){
            //去掉我的仇人
            synchronized (userData){
                userData.removeEnemy(targetPlayer.getUserData().getUserId());
                //
                robbedDartMap.put(targetPlayer.getUserData().getUserId(), enemyDartId);
                addUserBeatTime(userData, targetPlayer.getUserData().getUserId(), DateHelper.getCurrentSecond());
            }
            //添加他人的仇人
            if(robbedTime < ConfigMgr.getMaxRobTimesInLoss()) {
                synchronized (targetPlayer.getUserData()) {
                    targetPlayer.getUserData().addEnemy(userData.getUserId());
                }
            }
            //userData.getAttackRecord().put(targetPlayer.getUserData().getUserId(), new EscortAttackRecord(targetPlayer.getUserData().getUserId(), DateHelper.getCurrentSecond()));
            //商会贡献及美女经验奖励
            EscortDartTypeInfo typeInfo = ConfigMgr.getDartTypeInfoMap().get(type);
            Property robReward = PropertyHelper.parseStringToProperty(typeInfo.getRewards());
            robReward.rideProperty(ConfigMgr.getRobbedLossRatio());
            respMsg.setReward(PropertyHelper.parsePropertyToString(robReward));
            CrossBeautyEscortMgr.getLogger().debug("rob reward {}", respMsg.getReward());

            if(robbedTime < ConfigMgr.getMaxRobTimesInLoss()) {
                report = builderEnemyReport(targetPlayer, enemyDartId, startTime, type);
                List<Long> enemyUserIdList = new ArrayList<>();
                for (EnemyInfo enemyInfo : report.getEnemyInfoList()) {
                    enemyUserIdList.add(enemyInfo.getUserId());
                }
                enemyCartBuilder.addAllRobUser(enemyUserIdList);

                //推送被打通知
                notifyMsg = buildRobbedNotify(targetPlayer, respMsg.getReward(), enemyDartId);
                notifyMsg.setDartId(enemyDartId);
            }
        }
        respMsg.setWin(win);
        respMsg.setBuyConsume(buyConsume);
        respMsg.setEnemyCart(enemyCartBuilder);
        respMsg.addAllBuyBeauty(buyBeautyList);
        respMsg.setPosition(position);
        respMsg.setEnemyId(targetPlayer.getUserData().getUserId());
        MessageHelper.sendPacket(userData.getServerId(), userData.getUserId(), YanQuMessageUtils.buildMessage(Protocol.S_BEAUTY_ESCORT_ROB_CART_FROM_CROSS, respMsg));
        CrossBeautyEscortMgr.getLogger().debug("rob user {} dartId {}", targetPlayer.getUserData().getUserId(), enemyDartId);
        if(notifyMsg != null){
            MessageHelper.sendPacket(targetPlayer.getUserData().getServerId(), 0, YanQuMessageUtils.buildMessage(Protocol.S_BEAUTY_ESCORT_ROBBED_NOTIFY_FROM_CROSS, notifyMsg));
        }
        return 0;
    }

    private void addUserBeatTime(EscortUserData userData, long userId, int currentSecond) {
        Map<Long, EscortAttackRecord> attackRecord = userData.getAttackRecord();
        if(!attackRecord.containsKey(userId)){
            attackRecord.put(userId, new EscortAttackRecord());
        }
        long gap = DateHelper.HOUR_SECONDS * GameConfig.ESCORT_FIGHT_BACK_CONDITION;
        attackRecord.get(userId).getTime().removeIf(time -> currentSecond - time > gap);
        attackRecord.get(userId).getTime().add(currentSecond);
        userData.setUpdateOption();
    }

    /**
     * 反击
     */
    public int beatBack(CrossEscortPlayerWrap enemyPlayer, long enemyDartId, CrossEscortPlayerWrap friendPlayer, List<EscortBeautyDispatch> beautyList, List<Integer> buyBeautyList, String buyConsume, long dartId) {
       CrossBeautyEscortMgr.getLogger().debug(" {}：{} beat back {}:{}", friendPlayer.userData.getUserId(), dartId, enemyPlayer.getUserData().getUserId(), enemyDartId);
        //反击玩家的镖车
        EscortCartData cartData = enemyPlayer.getCartDataByDartId(enemyDartId);
        if(cartData == null){
            return GameErrorCode.E_BEAUTY_ESCORT_CART_NO_EXIST;
        }
        if(cartData.getState() != eEscortCartState.Escorting.getIntValue()){
            return GameErrorCode.E_BEAUTY_ESCORT_IS_FINISH;
        }
        //反击来源友商-战报
        EscortReport report = friendPlayer.getEscortReportByDartId(dartId);
        if(report == null){
            return GameErrorCode.E_BEAUTY_ESCORT_BEAT_BACK_ENTRY_OVER_TIME;
        }
        List<Long> enemyUserIdList = new ArrayList<>();
        for (EnemyInfo enemyInfo : report.getEnemyInfoList()) {
            enemyUserIdList.add(enemyInfo.getUserId());
        }
        //非法反击
        if(!enemyUserIdList.contains(enemyPlayer.getUserData().getUserId())){
            return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
        }
        //谁在反击
        synchronized (report){
            //已被反击
            if(report.getBeatBack().containsKey(enemyPlayer.getUserData().getUserId())){
                return GameErrorCode.E_BEAUTY_ESCORT_BEAT_BACK_HAD_COMPLETE;
            }
            //有人在反击
            if(report.getBeatingMap().containsKey(enemyPlayer.getUserData().getUserId())){
                return GameErrorCode.E_BEAUTY_ESCORT_BEAT_BACK_HAD_COMPLETE;
            }else {
                //我在反击
                report.getBeatingMap().put(enemyPlayer.getUserData().getUserId(), userData.getUserId());
            }
        }
        int startTime;
        boolean win;
        int robbedTime;
        int type;
        List<EscortBeautyDispatch> beautyDispatchList = cartData.getBeautyDispatchList();
        BeautyEscortProto.BeautyEscortCartTemp.Builder enemyCartBuilder;
        //判定劫镖次数
        synchronized (cartData) {//锁对手的镖车
            int state = enemyPlayer.getCartState(cartData);

            if (state != eEscortCartState.Escorting.getIntValue()) {
                report.getBeatingMap().remove(enemyPlayer.getUserData().getUserId(), userData.getUserId());
                return GameErrorCode.E_BEAUTY_ESCORT_IS_FINISH;
            }
            if (cartData.getEnemy().contains(userData.getUserId())) {
                report.getBeatingMap().remove(enemyPlayer.getUserData().getUserId(), userData.getUserId());
                return GameErrorCode.E_BEAUTY_ESCORT_CAN_NOT_ROB_SAME_DART;
            }
            if(cartData.getRobbedTimes() >= ConfigMgr.getMaxRobTimesInLoss()){
                report.getBeatingMap().remove(enemyPlayer.getUserData().getUserId(), userData.getUserId());
                return GameErrorCode.E_BEAUTY_ESCORT_CART_HAD_ROBBED_MANY;
            }
            //temp
            List<EscortBeautyDispatch> enemyCopy = new ArrayList<>();
            for (EscortBeautyDispatch dispatch : cartData.getBeautyDispatchList()) {
                enemyCopy.add(dispatch);
            }
            win = fight(beautyList, enemyCopy);
            robbedTime = cartData.getRobbedTimes();

            if(win) {
                //添加劫镖标识与次数
                if(cartData.getRobbedTimes() < ConfigMgr.getMaxRobTimesInLoss()) {
                    cartData.setRobbedTimes(cartData.getRobbedTimes() + 1);
                }
                //继续记录，但显示只取前几
                cartData.addEnemy(userData.getUserId());
            }

            startTime = cartData.getStartTime();
            type = cartData.getDartTypeId();
            enemyCartBuilder = BeautyEscortProto.BeautyEscortCartTemp.newBuilder();
            enemyCartBuilder.setDartId(enemyDartId);
            enemyCartBuilder.setCartId(cartData.getCartId());
            enemyCartBuilder.setCartType(cartData.getDartTypeId());
            enemyCartBuilder.setState(cartData.getState());
            enemyCartBuilder.setEventHandle(cartData.getEvent().isEnd());
            enemyCartBuilder.setStartTime(cartData.getStartTime());
            enemyCartBuilder.addAllBeauty(CrossBeautyEscortMgr.parseBeautyDispatchBuilderList(enemyCopy));
        }

        BeautyEscortProto.CrossBeautyEscortBeatBackRespMsg.Builder respMsg = BeautyEscortProto.CrossBeautyEscortBeatBackRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.addAllBeauty(CrossBeautyEscortMgr.parseBeautyDispatchBuilderList(beautyList));
        EscortReport enemyReport;
        BeautyEscortProto.BeautyEscortRobbedNotifyMsg.Builder notifyMsg = null;
        if (win){
            //去掉我的仇人
            synchronized (userData){
                userData.removeEnemy(enemyPlayer.getUserData().getUserId());

                robbedDartMap.put(enemyPlayer.getUserData().getUserId(), enemyDartId);

                addUserBeatTime(userData, enemyPlayer.getUserData().getUserId(), DateHelper.getCurrentSecond());
            }
            //添加他人的仇人
            if(robbedTime < ConfigMgr.getMaxRobTimesInLoss()) {
                synchronized (enemyPlayer.getUserData()) {
                    enemyPlayer.getUserData().addEnemy(userData.getUserId());
                }
            }
            //商会贡献及美女经验奖励
            EscortDartTypeInfo typeInfo = ConfigMgr.getDartTypeInfoMap().get(type);
            Property robReward = PropertyHelper.parseStringToProperty(typeInfo.getRewards());
            robReward.rideProperty(ConfigMgr.getRobbedLossRatio());
            respMsg.setReward(PropertyHelper.parsePropertyToString(robReward));
            //userData.getAttackRecord().put(enemyPlayer.getUserData().getUserId(), new EscortAttackRecord(enemyPlayer.getUserData().getUserId(), DateHelper.getCurrentSecond()));
            if(robbedTime < ConfigMgr.getMaxRobTimesInLoss()) {
                enemyReport = builderEnemyReport(enemyPlayer, enemyDartId, startTime, type);
                List<Long> enemyReportUidList = new ArrayList<>();
                for (EnemyInfo enemyInfo : enemyReport.getEnemyInfoList()) {
                    enemyUserIdList.add(enemyInfo.getUserId());
                }
                enemyCartBuilder.addAllRobUser(enemyReportUidList);
                //推送被打通知
                notifyMsg = buildRobbedNotify(enemyPlayer, respMsg.getReward(), enemyDartId);
            }
            synchronized (report){
                EscortBeatBack beatBack = new EscortBeatBack();
                beatBack.setBeatTime(DateHelper.getCurrentSecond());
                beatBack.setCartType(type);
                beatBack.setUserId(userData.getUserId());
                beatBack.setUnionUid(userBaseInfo.getUnionUid());
                beatBack.setRewards(respMsg.getReward());
                beatBack.setBeatTime(DateHelper.getCurrentSecond());
                long glamour = 0;
                for (EscortBeautyDispatch dispatch : beautyDispatchList) {
                    glamour += dispatch.getGlamour();
                }
                beatBack.setGlamour(glamour);
                report.getBeatBack().put(enemyPlayer.getUserData().getUserId(), beatBack);
                report.getBeatingMap().remove(enemyPlayer.getUserData().getUserId(), userData.getUserId());
                report.setUpdateOption();
            }
        }else {
            synchronized (report){
                report.getBeatingMap().remove(enemyPlayer.getUserData().getUserId(), userData.getUserId());
            }
        }
        respMsg.setWin(win);
        respMsg.setBuyConsume(buyConsume);
        respMsg.setEnemyCart(enemyCartBuilder);
        respMsg.addAllBuyBeauty(buyBeautyList);
        respMsg.setEnemyUserId(enemyPlayer.getUserData().getUserId());
        MessageHelper.sendPacket(userData.getServerId(), userData.getUserId(), YanQuMessageUtils.buildMessage(Protocol.S_BEAUTY_ESCORT_BEAT_BACK_FROM_CROSS, respMsg));
        if(notifyMsg != null){
            MessageHelper.sendPacket(enemyPlayer.getUserData().getServerId(), 0, YanQuMessageUtils.buildMessage(Protocol.S_BEAUTY_ESCORT_ROBBED_NOTIFY_FROM_CROSS, notifyMsg));
        }
        return 0;
    }

    private BeautyEscortProto.BeautyEscortRobbedNotifyMsg.Builder buildRobbedNotify(CrossEscortPlayerWrap targetPlayer, String rewards, long dartId) {
        BeautyEscortProto.BeautyEscortRobbedNotifyMsg.Builder notifyMsg = BeautyEscortProto.BeautyEscortRobbedNotifyMsg.newBuilder();
        notifyMsg.setRobbedUserId(targetPlayer.getUserData().getUserId());
        notifyMsg.setRobbedLoss(rewards);
        notifyMsg.setRobbedUserName(targetPlayer.getUserBaseInfo().getNickName());
        notifyMsg.setRobUserId(userData.getUserId());
        notifyMsg.setServerId(userData.getServerId());
        notifyMsg.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
        notifyMsg.setRobbedTime(DateHelper.getCurrentSecond());
        notifyMsg.setDartId(dartId);
        return notifyMsg;
    }

    /**
     * 劫镖-NPC
     */
    public int robNpcCart(int userId, long dartId, List<Integer> buyBeautyList, List<EscortBeautyDispatch> beautyDispatch, int position,  String buyConsume) {
        BeautyEscortProto.CrossBeautyEscortRobCartRespMsg.Builder respMsg = BeautyEscortProto.CrossBeautyEscortRobCartRespMsg.newBuilder();
        EscortBeautyMapNpc npc = userData.getRoadMapNPCUser().get(position);
        if(npc == null) {
            for (Map.Entry<Integer, EscortBeautyMapNpc> npcEntry : userData.getRoadMapNPCUser().entrySet()) {
                if (npcEntry.getValue().getId() == userId) {
                    npc = npcEntry.getValue();
                    break;
                }
            }
        }
        if(npc == null || npc.getId() != userId){
            return GameErrorCode.E_BEAUTY_ESCORT_CART_NO_EXIST;
        }
        synchronized (npc){
            if(npc.isRobbed()){
                return GameErrorCode.E_BEAUTY_ESCORT_CAN_NOT_ROB_SAME_DART;
            }
            EscortBeautyCartNPCInfo npcInfo = ConfigMgr.getEscortBeautyCartNPCInfo(userId);
            //temp
            List<EscortBeautyDispatch> enemyDispatchList = new ArrayList<>();
            if(npcInfo == null){
                return GameErrorCode.E_BEAUTY_ESCORT_CONFIG_NO_EXIST;
            }
            for (int beautyId : npcInfo.getBeautyList()) {
                EscortBeautyDispatch dispatch = new EscortBeautyDispatch();
                dispatch.setGlamour(npcInfo.getGlamour());
                dispatch.setBeautyId(beautyId);
                enemyDispatchList.add(dispatch);
            }
            boolean win = fight(beautyDispatch, enemyDispatchList);
            if(win){
                npc.setRobbed(true);
                userData.setUpdateOption();
                //商会贡献及美女经验奖励
                EscortDartTypeInfo typeInfo = ConfigMgr.getRobotDartCartType();
                Property robReward = PropertyHelper.parseStringToProperty(typeInfo.getRewards());
                robReward.rideProperty(ConfigMgr.getRobbedLossRatio());
                respMsg.setReward(PropertyHelper.parsePropertyToString(robReward));
            }
            respMsg.setEnemyCart(CrossBeautyEscortMgr.getBeautyEscortCartTemp(npcInfo));
            respMsg.setBuyConsume(buyConsume);
            respMsg.addAllBuyBeauty(buyBeautyList);
            respMsg.addAllBeauty(CrossBeautyEscortMgr.parseBeautyDispatchBuilderList(beautyDispatch));
            respMsg.setPosition(position);
            respMsg.setWin(win);
            respMsg.setRet(0);
            respMsg.setEnemyId(userId);
            MessageHelper.sendPacket(userData.getServerId(), userData.getUserId(), YanQuMessageUtils.buildMessage(Protocol.S_BEAUTY_ESCORT_ROB_CART_FROM_CROSS, respMsg));
        }
        return 0;
    }

    /**
     * 获取战报（根据走镖Id）
     */
    public EscortReport getEscortReportByDartId(long dartId) {
        return getEscortReportMap().get(dartId);
    }

    /**
     * 初始敌方战报
     */
    private EscortReport builderEnemyReport(CrossEscortPlayerWrap enemyPlayerWrap, long dartId, int startTime, int dartType) {
        //战报
        Map<Long, EscortReport> escortRecordMap = enemyPlayerWrap.getEscortReportMap();
        EscortReport escortRecord;
        synchronized (escortRecordMap) {
            if (escortRecordMap.containsKey(dartId)) {
                escortRecord = escortRecordMap.get(dartId);
            } else {
                escortRecord = new EscortReport();
                escortRecord.setDartId(dartId);
                escortRecord.setUserId(enemyPlayerWrap.getUserData().getUserId());
                escortRecord.setServerId(enemyPlayerWrap.getUserData().getServerId());
                escortRecord.setWeekId(CrossBeautyEscortRankMgr.getThisWeekId());
                escortRecord.setDartType(dartType);
                escortRecord.setInsertOption();
                escortRecord.setStartTime(startTime);
            }
            EnemyInfo enemyInfo = new EnemyInfo();
            enemyInfo.setUserId(userData.getUserId());
            enemyInfo.setTime(DateHelper.getCurrentSecond());
            escortRecord.addEnemyInfo(enemyInfo);
            escortRecord.setLatestRobTime(DateHelper.getCurrentSecond());
            escortRecord.setRobbedTimes(1 + escortRecord.getRobbedTimes());
            if(escortRecord.isInsertOption()){
                escortRecordMap.put(dartId, escortRecord);
            }
        }
        return escortRecord;
    }

    /**
     * 美女对打
     */
    private boolean fight(List<EscortBeautyDispatch> dispatchList, List<EscortBeautyDispatch> enemyDispatchList) {
        //随机敌方
        Random random = new Random();
        List<EscortBeautyDispatch> result = new ArrayList<>();
        while(enemyDispatchList.size() > 0){
            int idx = random.nextInt(enemyDispatchList.size());
            result.add(enemyDispatchList.remove(idx));
        }
        boolean win;
        int winTimes = 0;
        //我方顺序出
        for (int i = 0; i < dispatchList.size(); i++) {
            EscortBeautyDispatch me = dispatchList.get(i);
            EscortBeautyDispatch enemy = result.get(i);
            if(me == null || enemy == null){
                continue;
            }
            if(me.getGlamour() > enemy.getGlamour()){
                winTimes++;
            }
            //CrossBeautyEscortMgr.getLogger().info("{} vs {} , win:{}", me.getGlamour(), enemy.getGlamour(), me.getGlamour() > enemy.getGlamour());
        }
        if(winTimes >= (dispatchList.size() / 2 + 1)){
            win = true;
        }else {
            win = false;
        }
        enemyDispatchList.addAll(result);
        return win;
    }

    /**
     * 打事件boss
     */
    public int attackBoss(int cartId, long dartId) {
        EscortCartData cartData = getCartDataMap().get(cartId);
        if(cartData == null){
            return GameErrorCode.E_BEAUTY_ESCORT_CART_NO_EXIST;
        }
        boolean end;
        synchronized (cartData){
            if (System.currentTimeMillis() - cartData.getEvent().getLastAttackTime() < 100) {
                return GameErrorCode.E_BEAUTY_ESCORT_ATTACK_BOSS_OFTEN;
            }
            if(cartData.getDartId() != dartId){
                return GameErrorCode.E_BEAUTY_ESCORT_DART_NOT_MATCH;
            }
            EscortBeautyEvent event = cartData.getEvent();
            if(event.isEnd()){
                BeautyEscortProto.BeautyEscortAttackEventBossRespMsg.Builder respMsg = BeautyEscortProto.BeautyEscortAttackEventBossRespMsg.newBuilder();
                respMsg.setRet(0);
                respMsg.setEnd(true);
                respMsg.setAllDamage(event.getDamage());
                MessageHelper.sendPacket(userData.getServerId(), userData.getUserId(), YanQuMessageUtils.buildMessage(Protocol.U_BEAUTY_ESCORT_ATTACK_EVENT_BOSS, respMsg));
                //CrossBeautyEscortMgr.getLogger().info("attack end 1");
                return 0;
            }
            if(event.getEventId() <= 0){
                return GameErrorCode.E_BEAUTY_ESCORT_DART_NO_EVENT;
            }
            EscortBeautyEventBossInfo bossInfo = BeautyEscortConfigMgr.getEventBossInfoMap().get(event.getEventId());
            if(bossInfo == null){
                return GameErrorCode.E_BEAUTY_ESCORT_CONFIG_NO_EXIST;
            }
            if(event.getStart() <= 0){
                event.setStart(DateHelper.getCurrentSecond());
            }
            end = isAttackEnd(event, bossInfo);
            if(end){
                event.setEnd(true);
            }else {
                int ability = 0;
                for (EscortBeautyDispatch dispatch : cartData.getBeautyDispatchList()) {
                    ability += dispatch.getGlamour();
                }
                event.setDamage(ability + event.getDamage());
                event.setTimes(1 + event.getTimes());
                end = event.getDamage() >= bossInfo.getHp();
                cartData.getEvent().setEnd(end);
                //CrossBeautyEscortMgr.getLogger().info("{} attack {} times {}  damage {}, is end ? {}", userData.getUserId(), bossInfo.getId(), event.getTimes(), event.getDamage(), end);
                cartData.getEvent().setLastAttackTime(System.currentTimeMillis());
            }
            cartData.setUpdateOption();

            BeautyEscortProto.BeautyEscortAttackEventBossRespMsg.Builder respMsg = BeautyEscortProto.BeautyEscortAttackEventBossRespMsg.newBuilder();
            respMsg.setRet(0);
            respMsg.setEnd(end);
            respMsg.setAllDamage(event.getDamage());
            MessageHelper.sendPacket(userData.getServerId(), userData.getUserId(), YanQuMessageUtils.buildMessage(Protocol.U_BEAUTY_ESCORT_ATTACK_EVENT_BOSS, respMsg));
            //CrossBeautyEscortMgr.getLogger().info("attack end {}", end);
        }
        return 0;
    }

    /**
     * boss攻击是否结束（打死或者倒计时结束）
     */
    private boolean isAttackEnd(EscortBeautyEvent event, EscortBeautyEventBossInfo bossInfo) {
        if(event.isEnd()){
            return true;
        }
        boolean end;
        end = event.getDamage() >= bossInfo.getHp();
        if(!end){
            end = DateHelper.getCurrentSecond() - event.getStart() > GameConfig.ESCORT_EVENT_COUNTDOWN && event.getStart() > 0;
        }
        return end;
    }

    /**
     * 计算事件奖励
     */
    private String getEventReward(boolean win, long damage, EscortBeautyEventBossInfo bossInfo) {
        if(win){
            return bossInfo.getRewards();
        }else {
            Property property = PropertyHelper.parseStringToProperty(bossInfo.getRewards());
            property.rideProperty(BigDecimal.valueOf(damage).divide(BigDecimal.valueOf(bossInfo.getHp()), 3, BigDecimal.ROUND_UP));
            return PropertyHelper.parsePropertyToString(property);
        }
    }

    /**
     * 获取空闲的镖车
     */
    public EscortCartData getIdleEscortCartData() {
        EscortCartData idleCart = null;
        for (EscortCartData cartData : cartDataMap.values()) {
            if(isIdle(cartData)){
                if(idleCart == null) {
                    idleCart = cartData;
                }else if(cartData.getCartId() < idleCart.getCartId()){
                    //从id小的优先接镖
                    idleCart = cartData;
                }
            }
        }
        return idleCart;
    }

    /**
     * 镖车是否空闲
     */
    private boolean isIdle(EscortCartData cartData) {
        return cartData.getState() == eEscortCartState.Idle.getIntValue()
            ||(cartData.getState() == eEscortCartState.Finish.getIntValue() && cartData.isGetReward());
    }

    /**
     * 获取可劫镖车
     */
    public EscortCartData canRob(int hadRobTimes, long enemyId){
        return canRob(cartDataMap.values(), hadRobTimes, enemyId);
    }

    /**
     * 获取可劫镖车
     */
    private EscortCartData canRob(Collection<EscortCartData> cartDataList, int hadRobTimes, long enemyId){
        for(EscortCartData cartData : cartDataList){
            if(canRob(cartData, hadRobTimes, enemyId)){
                return cartData;
            }
        }
        return null;
    }

    /**
     * 是否可劫镖
     * 可劫镖条件：走镖中+被劫次数<hadRobTimes+未被enemyId劫过
     */
    public boolean canRob(EscortCartData cartData, int hadRobTimes, long enemyId){
        //计算镖车状态
        int state = getCartState(cartData);
        if(state == eEscortCartState.Escorting.getIntValue() && cartData.getRobbedTimes() < hadRobTimes && !cartData.getEnemy().contains(enemyId)){
            return true;
        }
        return false;
    }

    /**
     * 获取首辆走镖镖车
     */
    public EscortCartData getFirstEscortingCart(){
        for (EscortCartData data : cartDataMap.values()) {
            if(isEscorting(data)){
                return data;
            }
        }
        return null;
    }

    /**
     * 是否在走镖
     */
    public boolean isEscorting(EscortCartData cartData){
        //计算镖车状态
        int state = getCartState(cartData);
        if(state == eEscortCartState.Escorting.getIntValue()){
            return true;
        }
        return false;
    }

    public boolean calAllCartState(){
        boolean change = false;
        for (Map.Entry<Integer, EscortCartData> cartDataEntry : getCartDataMap().entrySet()) {
            if(calCartState(cartDataEntry.getValue())){
                change = true;
            }
        }
        return change;
    }

    /**
     * 定时器调用
     */
    public boolean calAllCartStateWithEvent(){
        //每日事件数重置
        long zeroTime = DateHelper.getTodayZeroTimeStamp();
        if(userData.getDayResetTime() != zeroTime){
            userData.setDayEventNum(0);
            userData.setDayResetTime(zeroTime);
        }

        boolean change = false;
        for (Map.Entry<Integer, EscortCartData> cartDataEntry : getCartDataMap().entrySet()) {
            if(calCartStateWithEvent(cartDataEntry.getValue())){
                change = true;
            }
        }
        return change;
    }

    /**
     * 计算镖车当前状态（包括事件触发），供定时器调用
     */
    public boolean calCartStateWithEvent(EscortCartData cartData) {
        synchronized (cartData) {
            if(cartData.getState() == eEscortCartState.Finish.getIntValue() || cartData.getState() == eEscortCartState.Idle.getIntValue()){
                return false;
            }
            int currentSecond = DateHelper.getCurrentSecond();
            int passSecond = currentSecond - cartData.getStartTime();

            try {
                //生成事件
                boolean hadEvent = generateEvent(cartData, passSecond);

                //通知玩家有事件
                if(hadEvent){
                    syncEventToUser(cartData.getCartId());
                }
                //自动处理事件
                autoHandleCartEvent(cartData);
            }catch (Exception e){
                CrossBeautyEscortMgr.getLogger().error("userId {}  cart {} handle event error : {}", cartData.getUserId(), cartData.getCartId(), e.getMessage());
            }

            int needTime = (cartData.getTakeTime() - cartData.getReduceTime()) * 60;
            if (passSecond >= needTime){
                cartData.setState(eEscortCartState.Finish.getIntValue());
                return true;
            }
            return false;
        }
    }

    private void syncEventToUser(int cartId) {
        try {
            BeautyEscortProto.BeautyEscortBossEventSyncMsg.Builder syncMsg = BeautyEscortProto.BeautyEscortBossEventSyncMsg.newBuilder();
            syncMsg.addCartId(cartId);
            MessageHelper.sendPacket(userData.getServerId(), userData.getUserId(), YanQuMessageUtils.buildMessage(Protocol.U_BEAUTY_ESCORT_BOSS_EVENT_SYNC, syncMsg));
        }catch(Exception e){
            CrossBeautyEscortMgr.getLogger().error(e.getMessage(), e);
        }
    }

    /**
     * 计算镖车当前状态（返回状态是否改变）
     */
    public boolean calCartState(EscortCartData cartData) {
        synchronized (cartData) {
            if(cartData.getState() == eEscortCartState.Finish.getIntValue() || cartData.getState() == eEscortCartState.Idle.getIntValue()){
                return false;
            }
            int currentSecond = DateHelper.getCurrentSecond();
            int passSecond = currentSecond - cartData.getStartTime();

            int needTime = (cartData.getTakeTime() - cartData.getReduceTime()) * 60;
            if (passSecond >= needTime){
                cartData.setState(eEscortCartState.Finish.getIntValue());
                return true;
            }
            return false;
        }
    }

    /**
     * 获取镖车最新状态（仅状态）
     */
    public int getCartState(EscortCartData cartData) {
        if(cartData.getState() == eEscortCartState.Finish.getIntValue() || cartData.getState() == eEscortCartState.Idle.getIntValue()){
            return cartData.getState();
        }
        int currentSecond = DateHelper.getCurrentSecond();
        int passSecond = currentSecond - cartData.getStartTime();

        int needTime = (cartData.getTakeTime() - cartData.getReduceTime()) * 60;
        if (passSecond >= needTime){
            return eEscortCartState.Finish.getIntValue();
        }
        return cartData.getState();
    }

    /**
     * 自动处理镖车事件
     */
    public void autoHandleCartEvent(EscortCartData cartData) {
        if(cartData.getEvent().getEventId() > 0 && cartData.isAutoHandleEvent() && !cartData.isGetEventReward()){
            EscortBeautyEventBossInfo bossInfo = BeautyEscortConfigMgr.getEventBossInfoMap().get(cartData.getEvent().getEventId());
            if(bossInfo != null) {
                if(!cartData.getEvent().isEnd()){
                    cartData.getEvent().setEnd(true);
                    cartData.getEvent().setStart(DateHelper.getCurrentSecond() - GameConfig.ESCORT_EVENT_COUNTDOWN);
                    //伤害赋值,自动处理拿最大奖励
                    cartData.getEvent().setDamage(bossInfo.getHp());
                    cartData.setUpdateOption();
                }
            }
        }
    }

    /**
     * 生成事件
     */
    private boolean generateEvent(EscortCartData cartData, int passSecond) {
        if(userData.getDayEventNum() < GameConfig.ESCORT_EVENT_TIMES_PER_DAY && cartData.getEvent().getEventId() == 0){
            //计算当前概率加成千分比
            int addition = getEventTriggerAddition(passSecond, cartData.getReduceTime(), cartData.getTakeTime());
            int point = addition / ConfigMgr.getEscortEventProbability().get(2);
            if(point == 0){
                return false;
            }
            boolean hasEvent = false;
            if(cartData.getEvent().getTriggerPoint() < point){
                for(int p = cartData.getEvent().getTriggerPoint(); p < point; p++){
                    //CrossBeautyEscortMgr.getLogger().info("user {} cart {}:{} trigger event at point {}:{}", cartData.getUserId(), cartData.getCartId(), cartData.getDartId(), point, p * BeautyEscortConfigMgr.ESCORT_EVENT_PROBABILITY.get(2));
                    if(triggerEvent(p * ConfigMgr.getEscortEventProbability().get(2))){
                        CrossBeautyEscortMgr.getLogger().debug("user {} cart {}:{} trigger event at point {}:{} success", cartData.getUserId(), cartData.getCartId(), cartData.getDartId(), point, p * ConfigMgr.getEscortEventProbability().get(2));
                        //随机一个事件
                        EscortBeautyEventBossInfo eventBossInfo = BeautyEscortConfigMgr.getRandomEventInfo(userData.getUnionLv());
                        if(eventBossInfo != null) {
                            cartData.getEvent().setEventId(eventBossInfo.getId());
                            cartData.getEvent().setEventTime(DateHelper.getCurrentSecond());
                            cartData.getEvent().setUnionLv(userData.getUnionLv());
                            cartData.getEvent().setUnionUid(userBaseInfo.getUnionUid());
                            //昨日出镖，不占用今日次数
                            if(cartData.getStartTime() > DateHelper.getTodayZeroTimeStamp() / 1000) {
                                userData.setDayEventNum(1 + userData.getDayEventNum());
                            }
                            hasEvent = true;
                        }
                        break;
                    }
                }
            }
            if(point > cartData.getEvent().getTriggerPoint()){
                cartData.getEvent().setTriggerPoint(point);
                cartData.setUpdateOption();
            }
            return hasEvent;
        }
        return false;
    }

    /**
     * 是否触发事件
     */
    private boolean triggerEvent(int addition){
        //初始概率 + 过去时间占比的概率加成
        int weight = (ConfigMgr.getEscortEventProbability().get(1)  + addition) / 10;
        if(weight >= 100){
            return true;
        }else {
            List<Integer> weightList = new ArrayList<>();
            weightList.add(weight);
            weightList.add(100 - weight);
            int idx = RandomHelper.getRandomIndexByWeight(weightList);
            if (idx == 0){
                return true;
            }
            return false;
        }
    }

    /**
     * 触发事件的概率加成（千分比）
     */
    private int getEventTriggerAddition(int passSecond, int reduceTime, int takeTime) {
        //(过去时间/ (总时间 / 总节点)) = 过去占比
        //过去占比 * 每份占比递增概率
        return BigDecimal.valueOf(passSecond + reduceTime * 60).divide(BigDecimal.valueOf(takeTime * 60 / ConfigMgr.getEscortEventProbability().get(0)), 3, BigDecimal.ROUND_UP)
                    .multiply(BigDecimal.valueOf(ConfigMgr.getEscortEventProbability().get(2))).setScale(0, BigDecimal.ROUND_UP).intValue();
    }

    /**
     * 获取下一趟走镖ID
     */
    private long getNextDartId(){
        long cur = 0;
        for (EscortCartData cartData : cartDataMap.values()) {
            if(cur < cartData.getDartId()) {
                cur = cartData.getDartId();
            }
        }
        return cur + 1;
    }

    /**
     * 重置镖车数据
     */
    private void resetCart(EscortCartData idleCart) {
        idleCart.setEvent(new EscortBeautyEvent());
        idleCart.setBeautyDispatchList(new ArrayList<>());
        idleCart.setGetReward(false);
        idleCart.setGetEventReward(false);
        idleCart.setReduceTime(0);
        idleCart.setRobbedTimes(0);
        idleCart.setStartTime(0);
        idleCart.setDartTypeId(0);
        idleCart.setEnemy(new ArrayList<>());
    }

    /**
     * 随机委托人（不可重复，有权重）
     */
    public void randomClient(){
        for(int i = userData.getClientList().size(); i < 3; i++){
            userData.getClientList().add(BeautyEscortConfigMgr.randomClient(userData.getClientList()));
            userData.setUpdateOption();
        }
    }

    /**
     * 领取事件奖励
     */
    public BeautyEscortProto.BeautyEscortGetEventRewardRespMsg.Builder getEventReward(int cartId, long dartId) {
        BeautyEscortProto.BeautyEscortGetEventRewardRespMsg.Builder respMsg = BeautyEscortProto.BeautyEscortGetEventRewardRespMsg.newBuilder();
        EscortCartData cartData = getCartDataMap().get(cartId);
        if(cartData == null){
            respMsg.setRet(GameErrorCode.E_BEAUTY_ESCORT_CART_NO_EXIST);
            return respMsg;
        }
        boolean win;
        synchronized (cartData) {
            if (cartData.isGetEventReward()) {
                respMsg.setRet(GameErrorCode.E_BEAUTY_ESCORT_DART_EVENT_REWARD_IS_SEND);
                return respMsg;
            }
            EscortBeautyEvent event = cartData.getEvent();
            if(event.getEventId() <= 0){
                respMsg.setRet(GameErrorCode.E_BEAUTY_ESCORT_DART_NO_EVENT);
                return respMsg;
            }
            if (cartData.getDartId() != dartId) {
                respMsg.setRet(GameErrorCode.E_BEAUTY_ESCORT_DART_NOT_MATCH);
                return respMsg;
            }
            EscortBeautyEventBossInfo bossInfo = BeautyEscortConfigMgr.getEventBossInfoMap().get(event.getEventId());
            if(bossInfo == null){
                respMsg.setRet(GameErrorCode.E_BEAUTY_ESCORT_CONFIG_NO_EXIST);
                return respMsg;
            }
            if(event.getStart() <= 0 && !cartData.isAutoHandleEvent()){
                respMsg.setRet(GameErrorCode.E_BEAUTY_ESCORT_DART_EVENT_NO_DONE);
                return respMsg;
            }
            if (!event.isEnd()) {
                boolean end = isAttackEnd(cartData.getEvent(), bossInfo);
                if (!end) {
                    respMsg.setRet(GameErrorCode.E_BEAUTY_ESCORT_DART_EVENT_NO_DONE);
                    return respMsg;
                }else {
                    event.setEnd(true);
                    cartData.setUpdateOption();
                }
            }
            win = event.getDamage() >= bossInfo.getHp();
            Property baseRewards = new Property();
            if(!StringUtils.isNullOrEmpty(bossInfo.getBaseRewards())){
                baseRewards = PropertyHelper.parseStringToProperty(bossInfo.getBaseRewards());
            }
            String reward = getEventReward(win, event.getDamage(), bossInfo);
            baseRewards.addProperty(PropertyHelper.parseStringToProperty(reward));
            cartData.setGetEventReward(true);

            respMsg.setRet(0);
            respMsg.setWin(win);
            respMsg.setReward(PropertyHelper.parsePropertyToString(baseRewards));
            respMsg.setAllDamage(event.getDamage());
            respMsg.setUnionUid(event.getUnionUid() == null ? "" : event.getUnionUid());
            respMsg.setUnionLv(event.getUnionLv());
            respMsg.setEventTime(event.getEventTime());
            respMsg.setEventId(event.getEventId());
            respMsg.setDartId(dartId);
            respMsg.addAllBeauty(CrossBeautyEscortMgr.parseBeautyDispatchBuilderList(cartData.getBeautyDispatchList()));
        }
        return respMsg;
    }

    /**
     * 领取走镖奖励
     */
    public EscortCartDataHelper getDartReward(int cartId, long dartId) {
        EscortCartDataHelper helper = new EscortCartDataHelper();
        EscortCartData cartData = getCartDataMap().get(cartId);
        if(cartData == null){
            helper.setRet(GameErrorCode.E_BEAUTY_ESCORT_CART_NO_EXIST);
            return helper;
        }
        synchronized (cartData) {
            if (cartData.getState() != eEscortCartState.Finish.getIntValue()){
                helper.setRet(GameErrorCode.E_BEAUTY_ESCORT_DART_NOT_FINISH);
                return helper;
            }
            if(cartData.getEvent().getEventId() > 0 && !cartData.getEvent().isEnd()){
                helper.setRet(GameErrorCode.E_BEAUTY_ESCORT_DART_EVENT_NO_DONE);
                return helper;
            }
            if(cartData.getEvent().isEnd() && !cartData.isGetEventReward()){
                helper.setRet(GameErrorCode.E_BEAUTY_ESCORT_DART_EVENT_NO_DONE);
                return helper;
            }
            if (cartData.isGetReward()) {
                helper.setRet(GameErrorCode.E_BEAUTY_ESCORT_DART_REWARD_IS_SEND);
                return helper;
            }
            if (cartData.getDartId() != dartId) {
                helper.setRet(GameErrorCode.E_BEAUTY_ESCORT_DART_NOT_MATCH);
                return helper;
            }
            EscortDartTypeInfo typeInfo = ConfigMgr.getDartTypeInfoMap().get(cartData.getDartTypeId());
            if(typeInfo == null){
                helper.setRet(GameErrorCode.E_BEAUTY_ESCORT_CONFIG_NO_EXIST);
                return helper;
            }
            cartData.setGetReward(true);
            cartData.setState(eEscortCartState.Idle.getIntValue());  //设置空闲

            Property dartRewardProperty = getDartRewardProperty(cartData);
            EscortReport report = getEscortReportByDartId(dartId);
            if(report != null){
                report.setReward(PropertyHelper.parsePropertyToString(dartRewardProperty));
            }
            helper.setReward(dartRewardProperty);
        }
        helper.setRet(0);
        helper.setIdleCart(cartData);
        return helper;
    }

    /**
     * 强制自动结算（退出商会、解散商会）
     */
    public int autoSettlement(long serverId, long userId, String unionUid) {
        BeautyEscortProto.CrossBeautyEscortNotifyQuitUnionRespMsg.Builder respMsg = BeautyEscortProto.CrossBeautyEscortNotifyQuitUnionRespMsg.newBuilder();
        for (EscortCartData cartData : cartDataMap.values()) {
            synchronized (cartData){
                if(cartData.isGetReward()){
                    continue;
                }
                //只针对走镖中的镖车
                if(cartData.getState() != eEscortCartState.Escorting.getIntValue()){
                    continue;
                }

                BeautyEscortProto.CrossBeautyEscortSettlementRewardTemp.Builder cartRewardBuilder = BeautyEscortProto.CrossBeautyEscortSettlementRewardTemp.newBuilder();
                cartRewardBuilder.setCartId(cartData.getCartId());

                //镖车奖励
                Property dartReward = getDartRewardProperty(cartData);
                cartRewardBuilder.setReward(PropertyHelper.parsePropertyToString(dartReward));

                //事件奖励
                if(!cartData.isGetEventReward() && cartData.getEvent().isEnd() && cartData.getEvent().getEventId() > 0){
                    EscortBeautyEventBossInfo bossInfo = BeautyEscortConfigMgr.getEventBossInfoMap().get(cartData.getEvent().getEventId());
                    String reward  = getEventReward(cartData.getEvent().getDamage() >= bossInfo.getHp(), cartData.getEvent().getDamage(), bossInfo);
                    cartRewardBuilder.setEventReward(reward);

                    cartData.getEvent().setReward(reward);
                    cartData.setGetEventReward(true);
                    CrossBeautyEscortMgr.getLogger().debug(" user {} autoSettlement, cart {}:{}", userId, cartData.getCartId(), cartData.getDartId());
                }
                cartData.setGetReward(true);
                cartData.setState(eEscortCartState.Finish.getIntValue());
                respMsg.addReward(cartRewardBuilder);
            }
        }

        respMsg.setUnionUid(unionUid);
        respMsg.setUserId(userId);
        MessageHelper.sendPacket(userData.getServerId(), userData.getUserId(), YanQuMessageUtils.buildMessage(Protocol.S_BEAUTY_ESCORT_QUIT_UNION_SETTLEMENT_REWARD_FROM_CROSS, respMsg));
        return 0;
    }

    /**
     * 走镖奖励
     */
    public Property getDartRewardProperty(EscortCartData cartData) {
        EscortDartTypeInfo typeInfo = ConfigMgr.getDartTypeInfoMap().get(cartData.getDartTypeId());
        Property dartReward = PropertyHelper.parseStringToProperty(typeInfo.getRewards());

        //扣除被劫损失
        dartReward.rideProperty(BigDecimal.valueOf(1).subtract(ConfigMgr.getRobbedLossRatio().multiply(BigDecimal.valueOf(cartData.getRobbedTimes()))));

        return dartReward;
    }

    /**
     * 获取走镖中的美女
     */
    public List<Integer> getEscortingBeautyIdList() {
        List<Integer> beautyIdList = new ArrayList<>();
        for (Map.Entry<Integer, EscortCartData> cartDataEntry : getCartDataMap().entrySet()) {
            if(cartDataEntry.getValue().getState() != eEscortCartState.Idle.getIntValue()){
                for (EscortBeautyDispatch dispatch : cartDataEntry.getValue().getBeautyDispatchList()) {
                    beautyIdList.add(dispatch.getBeautyId());
                }
            }
        }
        return beautyIdList;
    }

    /**
     * 按走镖id 获取镖车数据
     */
    public EscortCartData getCartDataByDartId(long dartId) {
        for (Map.Entry<Integer, EscortCartData> cartDataEntry : getCartDataMap().entrySet()) {
            if(cartDataEntry.getValue().getDartId() == dartId){
                return cartDataEntry.getValue();
            }
        }
        return null;
    }

    /**
     * 强制刷新前动作
     */
    public void preRefreshMap(){
        robbedDartMap.clear();
    }

    //builder
    /**
     * 官道-镖车详细信息
     */
    public List<BeautyEscortProto.BeautyEscortCartDetailTemp> getCartDetailTemp() {
        List<BeautyEscortProto.BeautyEscortCartDetailTemp> result = new ArrayList<>();
        for (EscortCartData cartData : cartDataMap.values()) {
            BeautyEscortProto.BeautyEscortCartDetailTemp.Builder builder = BeautyEscortProto.BeautyEscortCartDetailTemp.newBuilder();
            builder.setCartId(cartData.getCartId());
            builder.setState(cartData.getState());
            builder.setGetReward(cartData.isGetReward());
            builder.setGetEventReward(cartData.isGetEventReward());
            builder.setStartTime(cartData.getStartTime());
            builder.setTypeId(cartData.getDartTypeId());
            builder.setDartId(cartData.getDartId());
            builder.setClientId(cartData.getClientId());
            builder.setEventHandle(cartData.getEvent().isEnd());
            builder.setEventId(cartData.getEvent().getEventId());
            builder.setReduceTime(cartData.getReduceTime());
            builder.setDamage(cartData.getEvent().getDamage());
            builder.setAttackStart(cartData.getEvent().getStart());
            builder.setAutoHandleEvent(cartData.isAutoHandleEvent());
            builder.setRobbedTimes(cartData.getRobbedTimes());
            if(cartData.getClientId() > 0){
                builder.setTakeTime(cartData.getTakeTime());
            }
            for (EscortBeautyDispatch beautyDispatch : cartData.getBeautyDispatchList()) {
                builder.addBeauty(CrossBeautyEscortMgr.getBeautyDispatchBuilder(beautyDispatch.getBeautyId(), beautyDispatch.getGlamour()));
            }

            //攻击者
            EscortReport escortReport = getEscortReportByDartId(cartData.getDartId());
            if(escortReport != null){
                //暂不需要
                //builder.addAllRobUser(escortReport.getEnemy());
            }
            result.add(builder.build());
        }
        return result;
    }

    /**
     * 路线地图-玩家(位置0:代表玩家自己，)
     */
    public BeautyEscortProto.BeautyEscortRoadMapPlayerTemp.Builder getRoadMapPlayerBuilder(int position, long userId, List enemyList, long dartId) {
        BeautyEscortProto.BeautyEscortRoadMapPlayerTemp.Builder playerBuilder = BeautyEscortProto.BeautyEscortRoadMapPlayerTemp.newBuilder();
        playerBuilder.setUserId(userData.getUserId());
        playerBuilder.setServerId(userBaseInfo.getServerId());
        playerBuilder.setNickName(userBaseInfo.getNickName());
        playerBuilder.setPosition(position);
        playerBuilder.setTotalGlamour(userData.getTotalGlamour());
        playerBuilder.setDecoration(userBaseInfo.getDecoration());
        if(position == 0){
            //自己，返回走镖中的镖车
            for(EscortCartData cartData : cartDataMap.values()){
                if(!isEscorting(cartData)){
                    continue;
                }
                playerBuilder.addCart(CrossBeautyEscortMgr.getCartSimpleBuilder(cartData));
            }
        }else {
            //非自己，返回被劫过的镖车，否则返回可被劫的第一辆镖车
            if(dartId > 0){
                EscortCartData cartData = getCartDataByDartId(dartId);
                if(cartData != null){
                    playerBuilder.addCart(CrossBeautyEscortMgr.getCartSimpleBuilder(cartData));
                    //总魅力值改为镖车
                    long glamour = 0;
                    for (EscortBeautyDispatch dispatch : cartData.getBeautyDispatchList()) {
                        glamour += dispatch.getGlamour();
                    }
                    playerBuilder.setTotalGlamour(glamour);
                }
            }else {
                EscortCartData cartDataRobbable = canRob(ConfigMgr.getMaxRobTimesInLoss(), userId);
                if(cartDataRobbable != null){
                    playerBuilder.addCart(CrossBeautyEscortMgr.getCartSimpleBuilder(cartDataRobbable));
                    //总魅力值改为镖车
                    long glamour = 0;
                    for (EscortBeautyDispatch dispatch : cartDataRobbable.getBeautyDispatchList()) {
                        glamour += dispatch.getGlamour();
                    }
                    playerBuilder.setTotalGlamour(glamour);
                }
            }
        }

        playerBuilder.setUnionName(userBaseInfo.getUnionName());
        playerBuilder.setUserAliasId(userBaseInfo.getUserAliasId());
        playerBuilder.setTitleId(userBaseInfo.getTitleId());
        playerBuilder.setUnionUid(userBaseInfo.getUnionUid());
        playerBuilder.setCity(userBaseInfo.getCity());

        if(position == 0){
            playerBuilder.setEnemy(false);
        }else {
            playerBuilder.setEnemy(enemyList.contains(userData.getUserId()));
        }
        return playerBuilder;
    }

    /**
     * 路线地图-玩家(NPC)
     */
    private List<BeautyEscortProto.BeautyEscortRoadMapPlayerTemp> getAllRoadMapNPCPlayer() {
        List<BeautyEscortProto.BeautyEscortRoadMapPlayerTemp> npcList = new ArrayList<>();
        for (Map.Entry<Integer, EscortBeautyMapNpc> entry : userData.getRoadMapNPCUser().entrySet()) {
            int position = entry.getKey();
            int npcId = entry.getValue().getId();
            EscortBeautyCartNPCInfo npcInfo = ConfigMgr.getEscortBeautyCartNPCInfo(npcId);
            if(npcInfo != null) {
                BeautyEscortProto.BeautyEscortRoadMapPlayerTemp.Builder playerBuilder = BeautyEscortProto.BeautyEscortRoadMapPlayerTemp.newBuilder();
                playerBuilder.setUserId(npcId);
                playerBuilder.setServerId(0);
                playerBuilder.setNickName("");
                playerBuilder.setPosition(position);
                playerBuilder.setTotalGlamour(5 * npcInfo.getGlamour());
                BeautyEscortProto.BeautyEscortCartSimpleTemp.Builder cartSimpleBuilder = CrossBeautyEscortMgr.getCartSimpleBuilder(npcInfo);
                if(entry.getValue().isRobbed()){
                    cartSimpleBuilder.addRobUser(userData.getUserId());
                }
                playerBuilder.addCart(cartSimpleBuilder);
                playerBuilder.setDecoration("");
                playerBuilder.setNpc(true);
                playerBuilder.setEnemy(false);
                npcList.add(playerBuilder.build());
            }
        }
        return npcList;
    }

    /**
     * 路线地图-玩家-简要信息
     */
    public List<BeautyEscortProto.BeautyEscortCartSimpleTemp> getCartSimpleTemp() {
        List<BeautyEscortProto.BeautyEscortCartSimpleTemp> result = new ArrayList<>();
        for (EscortCartData cartData : cartDataMap.values()) {
            result.add(CrossBeautyEscortMgr.getCartSimpleBuilder(cartData).build());
        }
        return result;
    }

    /**
     * 获取镖车情报
     */
    public BeautyEscortProto.BeautyEscortEnemyCartRespMsg.Builder getEnemyCartRespBuilder(int cartId) {
        BeautyEscortProto.BeautyEscortEnemyCartRespMsg.Builder builder = BeautyEscortProto.BeautyEscortEnemyCartRespMsg.newBuilder();
        builder.setRet(0);
        builder.setUserId(userData.getUserId());
        builder.setServerId(userBaseInfo.getServerId());
        builder.setUserInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
        long glamour = 0;
        BeautyEscortProto.BeautyEscortCartTemp.Builder cartBuilder = BeautyEscortProto.BeautyEscortCartTemp.newBuilder();
        EscortCartData cartData = getCartDataMap().get(cartId);
        cartBuilder.setCartId(cartId);
        for (EscortBeautyDispatch dispatchEntry : cartData.getBeautyDispatchList()) {
            cartBuilder.addBeauty(CrossBeautyEscortMgr.getBeautyDispatchBuilder(dispatchEntry.getBeautyId(), dispatchEntry.getGlamour()));
            glamour += dispatchEntry.getGlamour();
        }
        builder.setTotalGlamour(glamour);
        cartBuilder.setStartTime(cartData.getStartTime());
        cartBuilder.setEventHandle(cartData.getEvent().isEnd());
        cartBuilder.setState(cartData.getState());

        builder.setCart(cartBuilder);
        return builder;
    }

    //get/set
    public EscortUserData getUserData() {
        return userData;
    }

    public void setUserData(EscortUserData userData) {
        this.userData = userData;
    }

    public UserBaseInfo getUserBaseInfo() {
        return userBaseInfo;
    }

    public void setUserBaseInfo(UserBaseInfo userBaseInfo) {
        this.userBaseInfo = userBaseInfo;
    }

    public Map<Integer, EscortCartData> getCartDataMap() {
        return cartDataMap;
    }

    public void setCartDataMap(Map<Integer, EscortCartData> cartDataMap) {
        this.cartDataMap = cartDataMap;
    }

    public Map<Integer, CrossEscortPlayerWrap> getRoadMapPlayer() {
        return roadMapPlayer;
    }

    public void setRoadMapPlayer(Map<Integer, CrossEscortPlayerWrap> roadMapPlayer) {
        roadMapPlayer = roadMapPlayer;
    }

    public Map<Long, EscortReport> getEscortReportMap() {
        return escortReportMap;
    }

    public void setEscortReportMap(Map<Long, EscortReport> escortReportMap) {
        this.escortReportMap = escortReportMap;
    }

    public List<Map.Entry<Long, EscortReport>> getEscortReportList(){
        List<Map.Entry<Long, EscortReport>> list = new ArrayList<>(escortReportMap.entrySet());
        CrossBeautyEscortReportSort sort = new CrossBeautyEscortReportSort();
        list.sort(sort);
        return list;
    }

    public void repair(long userId, String param){



    }

    /**
    * 描述：自动加速
    * 作者：zrq
    * 时间：2022/12/27
    * 参数：

    * 返回值：
    **/
    public void autoAccelerate(EscortCartData cartData) {
        if(cartData.getEvent().getEventId() > 0 && cartData.isAutoHandleEvent() && !cartData.isGetEventReward()){
            EscortBeautyEventBossInfo bossInfo = BeautyEscortConfigMgr.getEventBossInfoMap().get(cartData.getEvent().getEventId());
            if(bossInfo != null) {
                if(!cartData.getEvent().isEnd()){
                    cartData.getEvent().setEnd(true);
                    cartData.getEvent().setStart(DateHelper.getCurrentSecond() - GameConfig.ESCORT_EVENT_COUNTDOWN);
                    //伤害赋值,自动处理拿最大奖励
                    cartData.getEvent().setDamage(bossInfo.getHp());
                    cartData.setUpdateOption();
                }
            }
        }
    }
}
